<template>
    <view class="container">
        <canvas
            ref="gameCanvas"
            class="game-canvas"
            @touchstart="handleTouchStart"
            @touchmove="handleTouchMove"
            @touchend="handleTouchEnd"
        ></canvas>
        <view v-if="gameOver" class="game-over"> Game Over! Your score: {{ score }} </view>
        <!-- 下一组形状 -->
        <view class="next-shape">
            <canvas ref="nextShapeCanvas" class="next-shape-canvas"></canvas>
        </view>
        <view class="controls">
            <button @click="moveLeft">Left</button>
            <button @click="moveDown">Down</button>
            <button @click="moveRight">Right</button>
            <button @click="rotate">Rotate</button>
            <button @click="dropToBottom">Drop</button>
        </view>
    </view>
</template>

<script>
export default {
    data() {
        return {
            canvasWidth: 300,
            canvasHeight: 600,
            blockSize: 30,
            canvasContext: null,
            currentShape: null,
            nextShape: null,
            gameInterval: null,
            board: null,
            gameOver: false,
            score: 0,
            shapes: [
                // I shape
                [
                    [0, 0, 0, 0],
                    [1, 1, 1, 1],
                    [0, 0, 0, 0],
                    [0, 0, 0, 0],
                ],
                // O shape
                [
                    [1, 1],
                    [1, 1],
                ],
                // T shape
                [
                    [0, 1, 0],
                    [1, 1, 1],
                    [0, 0, 0],
                ],
                // S shape
                [
                    [0, 1, 1],
                    [1, 1, 0],
                    [0, 0, 0],
                ],
                // Z shape
                [
                    [1, 1, 0],
                    [0, 1, 1],
                    [0, 0, 0],
                ],
                // J shape
                [
                    [1, 0, 0],
                    [1, 1, 1],
                    [0, 0, 0],
                ],
                // L shape
                [
                    [0, 0, 1],
                    [1, 1, 1],
                    [0, 0, 0],
                ],
            ],
            shapeColors: [
                "#0BFBFD", // I 形状
                "#FFFF54", // O 形状
                "#8C1AF5", // T 形状
                "#75FB4C", // S 形状
                "#EA3323", // Z 形状
                "#0000FF", // J 形状
                "F3AE3D", // L 形状
            ],
        };
    },
    mounted() {
        this.board = Array.from(
            {
                length: this.canvasHeight / this.blockSize,
            },
            () => Array(this.canvasWidth / this.blockSize).fill(0)
        );
        this.canvasContext = this.$refs.gameCanvas.getContext("2d");
        this.nextShapeCanvasContext = this.$refs.nextShapeCanvas.getContext("2d");
        if (!this.canvasContext || !this.nextShapeCanvasContext) {
            console.error("Failed to get canvas context");
            return;
        }
        const canvas = this.$refs.gameCanvas;
        canvas.width = this.canvasWidth;
        canvas.height = this.canvasHeight;
        const nextShapeCanvas = this.$refs.nextShapeCanvas;
        nextShapeCanvas.width = 120;
        nextShapeCanvas.height = 120;
        this.currentShape = this.createShape();
        this.nextShape = this.createShape();
        this.drawShape(this.currentShape);
        this.drawNextShape(this.nextShape);
        this.gameInterval = setInterval(this.moveShapeDown, 1000);
    },
     methods: {
        handleTouchStart(event) {
            if (this.gameOver) {
                this.gameOver = false;
                this.board = Array.from(
                    {
                        length: this.canvasHeight / this.blockSize,
                    },
                    () => Array(this.canvasWidth / this.blockSize).fill(0)
                );
                this.currentShape = this.createShape();
                this.nextShape = this.createShape();
                this.drawShape(this.currentShape);
                this.drawNextShape(this.nextShape);
                this.gameInterval = setInterval(this.moveShapeDown, 1000);
                this.score = 0;
            }
        },
        handleTouchMove(event) {
            if (!this.gameOver) {
                const touchX = event.touches[0].clientX;
                const touchY = event.touches[0].clientY;
                const dx = touchX > this.canvasWidth / 2 ? 1 : -1;
                if (this.canMove(this.currentShape, dx, 0)) {
                    this.clearShape(this.currentShape);
                    this.currentShape.x += dx;
                    this.drawShape(this.currentShape);
                }
            }
        },
        handleTouchEnd(event) {
            if (!this.gameOver) {
                this.rotateShape(this.currentShape);
            }
        },
        moveLeft() {
            if (!this.gameOver && this.canMove(this.currentShape, -1, 0)) {
                this.clearShape(this.currentShape);
                this.currentShape.x -= 1;
                this.drawShape(this.currentShape);
            }
        },
        moveDown() {
            if (!this.gameOver && this.canMove(this.currentShape, 0, 1)) {
                this.clearShape(this.currentShape);
                this.currentShape.y += 1;
                this.drawShape(this.currentShape);
            }
        },
        moveRight() {
            if (!this.gameOver && this.canMove(this.currentShape, 1, 0)) {
                this.clearShape(this.currentShape);
                this.currentShape.x += 1;
                this.drawShape(this.currentShape);
            }
        },
        rotate() {
            if (!this.gameOver) {
                this.rotateShape(this.currentShape);
            }
        },
        dropToBottom() {
            if (!this.gameOver) {
                while (this.canMove(this.currentShape, 0, 1)) {
                    this.clearShape(this.currentShape);
                    this.currentShape.y += 1;
                    this.drawShape(this.currentShape);
                }
                this.lockShape(this.currentShape);
                this.currentShape = this.nextShape;
                this.nextShape = this.createShape();
                if (!this.canMove(this.currentShape, 0, 0)) {
                    this.gameOver = true;
                    clearInterval(this.gameInterval);
                    return;
                }
                this.drawShape(this.currentShape);
                this.drawNextShape(this.nextShape);
            }
        },
        createShape() {
            const shapeIndex = Math.floor(Math.random() * this.shapes.length);
            const shape = this.shapes[shapeIndex];
            const rows = shape.length;
            const cols = shape[0].length;
            return {
                x: Math.floor((this.canvasWidth / this.blockSize - cols) / 2),
                y: -rows,
                shape: shape,
                color: this.shapeColors[shapeIndex], // 添加颜色属性
            };
        },
        drawShape(shape) {
            console.log("Drawing shape:", shape);
            const shapeIndex = this.shapes.indexOf(shape.shape);
            const color = this.shapeColors[shapeIndex];

            // 清除当前形状
            this.clearShape(shape);

            // 绘制当前形状
            shape.shape.forEach((row, y) => {
                row.forEach((block, x) => {
                    if (block) {
                        this.canvasContext.fillStyle = color;
                        this.canvasContext.fillRect(
                            (shape.x + x) * this.blockSize,
                            (shape.y + y) * this.blockSize,
                            this.blockSize,
                            this.blockSize
                        );
                        this.canvasContext.strokeStyle = "#000";
                        this.canvasContext.lineWidth = 2;
                        this.canvasContext.strokeRect(
                            (shape.x + x) * this.blockSize,
                            (shape.y + y) * this.blockSize,
                            this.blockSize,
                            this.blockSize
                        );
                    }
                });
            });

            // 绘制落下阴影
            const shadowShape = { ...shape };
            while (this.canMove(shadowShape, 0, 1)) {
                shadowShape.y += 1;
            }
            shadowShape.shape.forEach((row, y) => {
                row.forEach((block, x) => {
                    if (block) {
                        this.canvasContext.fillStyle = "rgba(0, 0, 0, 0.5)";
                        this.canvasContext.fillRect(
                            (shadowShape.x + x) * this.blockSize,
                            (shadowShape.y + y) * this.blockSize,
                            this.blockSize,
                            this.blockSize
                        );
                    }
                });
            });
        },
        clearShape(shape) {
            shape.shape.forEach((row, y) => {
                row.forEach((block, x) => {
                    if (block) {
                        this.canvasContext.clearRect(
                            (shape.x + x) * this.blockSize,
                            (shape.y + y) * this.blockSize,
                            this.blockSize,
                            this.blockSize
                        );
                    }
                });
            });
        },
        moveShapeDown() {
            if (!this.canMove(this.currentShape, 0, 1)) {
                this.lockShape(this.currentShape);
                this.currentShape = this.nextShape;
                this.nextShape = this.createShape();
                if (!this.canMove(this.currentShape, 0, 0)) {
                    this.gameOver = true;
                    clearInterval(this.gameInterval);
                    return;
                }
                this.drawShape(this.currentShape);
                this.drawNextShape(this.nextShape);
            } else {
                this.clearShape(this.currentShape);
                this.currentShape.y += 1;
                this.drawShape(this.currentShape);
            }
        },
        canMove(shape, dx, dy) {
            const { x, y, shape: shapeMatrix } = shape;
            const rows = shapeMatrix.length;
            const cols = shapeMatrix[0].length;
            for (let i = 0; i < rows; i++) {
                for (let j = 0; j < cols; j++) {
                    if (shapeMatrix[i][j]) {
                        const newX = x + j + dx;
                        const newY = y + i + dy;
                        if (newX < 0 || newX >= this.canvasWidth / this.blockSize || newY >= this.canvasHeight / this.blockSize) {
                            return false;
                        }
                        if (this.board[newY] && this.board[newY][newX]) {
                            return false;
                        }
                    }
                }
            }
            return true;
        },
        lockShape(shape) {
            const { x, y, shape: shapeMatrix } = shape;
            const rows = shapeMatrix.length;
            const cols = shapeMatrix[0].length;
            for (let i = 0; i < rows; i++) {
                for (let j = 0; j < cols; j++) {
                    if (shapeMatrix[i][j]) {
                        this.board[y + i][x + j] = 1;
                    }
                }
            }
            this.clearLines();
        },
        clearLines() {
            let linesCleared = 0;
            for (let i = 0; i < this.board.length; i++) {
                if (this.board[i].every((block) => block)) {
                    this.board.splice(i, 1);
                    this.board.unshift(Array(this.canvasWidth / this.blockSize).fill(0));
                    linesCleared++;
                }
            }
            this.score += linesCleared * 10; // 每清除一行，增加10分
        },
        rotateShape(shape) {
            const { x, y, shape: shapeMatrix } = shape;
            const rows = shapeMatrix.length;
            const cols = shapeMatrix[0].length;
            const newShapeMatrix = Array.from(
                {
                    length: cols,
                },
                () => Array(rows).fill(0)
            );
            for (let i = 0; i < rows; i++) {
                for (let j = 0; j < cols; j++) {
                    newShapeMatrix[j][rows - 1 - i] = shapeMatrix[i][j];
                }
            }
            const newShape = {
                x,
                y,
                shape: newShapeMatrix,
            };
            if (this.canMove(newShape, 0, 0)) {
                this.clearShape(shape);
                shape.shape = newShapeMatrix;
                this.drawShape(shape);
            }
        },
        drawNextShape(shape) {
            this.nextShapeCanvasContext.clearRect(0, 0, 120, 120);
            const shapeIndex = this.shapes.indexOf(shape.shape);
            const color = this.shapeColors[shapeIndex];
            shape.shape.forEach((row, y) => {
                row.forEach((block, x) => {
                    if (block) {
                        this.nextShapeCanvasContext.fillStyle = color;
                        this.nextShapeCanvasContext.fillRect(
                            x * 30,
                            y * 30,
                            30,
                            30
                        );
                        this.nextShapeCanvasContext.strokeStyle = "#000";
                        this.nextShapeCanvasContext.lineWidth = 2;
                        this.nextShapeCanvasContext.strokeRect(
                            x * 30,
                            y * 30,
                            30,
                            30
                        );
                    }
                });
            });
        },
    },
};
</script>

<style>
.game-canvas {
    width: 300px;
    height: 600px;
    background-color: #000;
}
.game-over {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    color: white;
    font-size: 24px;
}
.controls {
    display: flex;
    justify-content: space-around;
    margin-top: 10px;
}
</style>
